﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using WindowsPhone_Map_TTTN.Resources;
using Microsoft.Phone.Maps.Controls;
using Windows.Devices.Geolocation;
using System.IO.IsolatedStorage;
using Microsoft.Phone.Maps.Services;
using Microsoft.Phone.Maps;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Threading.Tasks;
using System.IO;
using System.Text;
using Newtonsoft.Json;
using System.Device.Location;


namespace WindowsPhone_Map_TTTN
{
    class MapModelView
    {
        protected MapModel _model;

        protected MDb _db;

        protected Map _map;

        protected MapView _view;

        public MapModelView(MainPage mainPage)
        {

            //Init shelf config
            this._model = new MapModel();

            //Init MFactory
            MFactory.setMainPage(mainPage);

            //Init some element
            this._map = MFactory.getMap();
            this._db = MFactory.getDb();
            this._view = MFactory.getView();

        }

        //Init map

        public void initMap()
        {
            try
            {
                _map.Center = new GeoCoordinate(10.8, 106.660);
                _map.ZoomLevel = 11;
                //OpenSreetMap osm = new OpenSreetMap();
                //map.TileSources.Add(osm);
               
            }
            catch (Exception ex)
            {
                // return;
            }

        }

   

        public void home(object sender, EventArgs e)
        {
            goCurrentLocation();
            autoUpdate();
        }



        public void routing(object sender, EventArgs e)
        {

        }
        public void zoomIn(object sender, EventArgs e)
        {
            try
            {
                this._map.ZoomLevel++;
            }
            catch (Exception ex)
            {
                return;
            }
        }

        public void zoomOut(object sender, EventArgs e)
        {
            try
            {
                this._map.ZoomLevel--;
            }
            catch (Exception ex)
            {
                return;
            }

        }

        private async void goCurrentLocation()
        {
            try
            {
                this._map.Center = await getLocaltion();
                this._map.ZoomLevel = MConfig.default_zoomlevel;

            }
            catch (Exception ex)
            {
                return;
            }
        }
        private async Task<System.Device.Location.GeoCoordinate> getLocaltion()
        {
            try
            {
                Geolocator geolocator = new Windows.Devices.Geolocation.Geolocator();
                geolocator.DesiredAccuracyInMeters = 50;
                geolocator.DesiredAccuracy = PositionAccuracy.High;
                geolocator.MovementThreshold = 100;
                Geoposition geoposition = await geolocator.GetGeopositionAsync();
                Geocoordinate temp = geoposition.Coordinate;

                return new GeoCoordinate
                    (
                    temp.Latitude,
                    temp.Longitude,
                    temp.Altitude ?? Double.NaN,
                    temp.Accuracy,
                    temp.AltitudeAccuracy ?? Double.NaN,
                    temp.Speed ?? Double.NaN,
                    temp.Heading ?? Double.NaN
                    );
            }
            catch (Exception ex) { return null; }
        }
        /**
         * auto udate and sent to server**/
        private void autoUpdate()
        {
            setGPSToServer();
            autoTracking();
        }

        private async void autoTracking()
        {
            try
            {
                while (true)
                {
                    GeoCoordinate gps = await this.getLocaltion();
                    _map.Center = gps;
                    _view.addHomePoint(gps.Longitude, gps.Latitude);
                    System.Threading.Thread.Sleep(MConfig.tracking_timer);
                }


            }
            catch (Exception ex)
            {
                return;
            }
        }
        private async void setGPSToServer()
        {
            try
            {
                MapSocketUDP client = MFactory.getSocketUDP();
                while (true)
                {
                    GeoCoordinate gps = await this.getLocaltion();
                    MapUDPPackage data = new MapUDPPackage(gps);
                    String result = client.send(data.toString());

                    if (MConfig.debug)
                    {

                        System.Diagnostics.Debug.WriteLine(result);
                        System.Diagnostics.Debug.WriteLine(result);
                    }
                    System.Threading.Thread.Sleep(MConfig.gps_timer);
                }
                
                
            }
            catch (Exception ex)
            {
                return;
            }
        }


    }
}
